<?php

namespace app\controller\backend;

use app\model\BigField;
use app\model\Category;
use app\model\CategorySubContent;
use app\model\SubContent;
use app\model\Theme;
use app\model\ThemeFile;
use app\model\Website;
use app\model\WebsiteSetting;
use app\service\ApiService;
use app\service\ThemeFileService;
use app\service\ThemeService;
use app\validate\WebsiteSettingValidate;
use think\exception\ValidateException;
use think\response\Json;

class DesignController extends BaseController
{
    protected $designBase = 'public/design/designPage';

    protected function sanitizeFileName($file)
    {
        //sanitize, remove double dot .. and remove get parameters if any
        $file = CMS_ROOT . 'public/design/designPage/' . preg_replace('@\?.*$@', '', preg_replace('@\.{2,}@', '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file)));
        return $file;
    }

    public function save()
    {
        return $this->publish(1);

//        $param = $this->request->param();
//        // 数据验证
//        try {
//            validate(WebsiteSettingValidate::class)->scene('read')->check($param);
//        } catch (ValidateException $e) {
//            return jsonReturn(-1, $e->getError());
//        }
//
//        define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//2 Megabytes max html file size
//
//        $html = "";
//        if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
//            $startTemplateUrl = $this->sanitizeFileName($_POST['startTemplateUrl']);
//            $html = file_get_contents($startTemplateUrl);
//        } else if (isset($_POST['html'])) {
//            $html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
//        }
//
//        $where = [
//            'seller_id' => $this->admin['seller_id'],
//            'website_id' => $param['website_id'],
//            'lang' => $param['lang'],
//            'is_active' => 1
//        ];
//        $Theme = new Theme();
//        $theme = $Theme->getActiveTheme($where)['data']->toArray();
//        $themeName = $theme['theme'];
//
//        $pathInfo = pathinfo($param['file']);
//        $filename = $pathInfo['filename'];
////        $file = $this->sanitizeFileName($_POST['file']);
//        $file = CMS_ROOT .  "view/website/{$param['website_id']}/{$param['lang']}/{$themeName}/single_{$filename}.html";
//
//        if (file_put_contents($file, $html)) {
//            echo "保存成功 $file";
//        } else {
//            header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
//            echo "保存失败！  $file\n可能的原因是缺少写权限或文件路径不正确！";
//        }
//        exit();
    }

    /**
     * @param $saveType 1保存2发布
     * @return Json|void
     */
    public function publish($saveType = 2)
    {
        $param = $this->request->param();
        // 数据验证
        try {
            validate(WebsiteSettingValidate::class)->scene('read')->check($param);
        } catch (ValidateException $e) {
            return jsonReturn(-1, $e->getError());
        }

        define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//2 Megabytes max html file size

        $html = "";
        if (isset($param['startTemplateUrl']) && !empty($param['startTemplateUrl'])) {
            $startTemplateUrl = $this->sanitizeFileName($param['startTemplateUrl']);
            $html = file_get_contents($startTemplateUrl);
        } else if (isset($_POST['html'])) {
            $html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
        }

        preg_match_all( '~<img.*?src=["\']+(.*?)["\']+.*>~' , $html, $match );

        $imgTagArr = $match[0];
        $imgSrcArr = $match[1];
        $maxImgSize = config('system.lazy_load_size');  // 读取文件大小，大于 配置文件 做懒加载

        $oldImgTagArr = [];
        $newImgTagArr = [];

        foreach ($imgSrcArr as $key => $value) {
            // 存在无需懒加载的标签，跳过
            if (strpos($imgTagArr[$key], 'no-lazy') !== false) {
                continue;
            }

            if (empty($value)) {
                continue;
            }
            if (strpos($value, 'data:') === 0) {
                continue;
            }

            if (strpos($value, 'http:') === 0) {
                $fileUrl = $value;

                $res = @get_headers($fileUrl,true);
                if (!isset($res['Content-Length'])) {
                    continue;
                }

                $filesize = round($res['Content-Length']/1024,2);
            }
            else {
                $publicPath = CMS_ROOT . 'public';
                if (strpos($value, '/') !== 0) {
                    $publicPath .= '/';
                }
                $fileUrl = $publicPath . $value;

                if (!file_exists($fileUrl)) {
                    continue;
                }

                $filesize = filesize($fileUrl);
                $filesize /= pow(1024, 1);
            }

            if ($filesize > $maxImgSize) {
                $imgTagArr[$key] =  str_replace("data-src='{$value}'", '', $imgTagArr[$key]);

                $imgTagReplace = str_replace($value, '/system_file/loading.png', $imgTagArr[$key]);
                $replaceStr = " data-src='{$value}' ";
                $imgTagReplace = substr_replace($imgTagReplace, $replaceStr, 4, 0);
                $oldImgTagArr[] = $imgTagArr[$key];
                $newImgTagArr[] = $imgTagReplace;
            }
        }

        if (!empty($oldImgTagArr)) {
            $html = str_replace($oldImgTagArr, $newImgTagArr, $html);
        }

        $jsStr = '
<script id="loadingJs" src="/system_file/js/huocms-loading.js"></script>
</head>';

        if (strpos($html, '/system_file/js/huocms-loading.js') === false) {
            $html = str_replace('</head>', $jsStr, $html);
        }

        $html = \phpQuery::newDocument($html);

        // 根据section的顺序确定各个部分插入的顺序

        $html['head #viewHelp']->remove();//移除可视化时用于方便界面编辑的css

        $blockHtmlArr = [];
        $where = [
            'seller_id' => $this->admin['seller_id'],
            'website_id' => $param['website_id'],
            'lang' => $param['lang'],
            'is_active' => 1
        ];
        $Theme = new Theme();
        $themeFileModel = new ThemeFile();
        $theme = $Theme->getActiveTheme($where)['data']->toArray();
        $themeName = $theme['theme'];

        $BigField = new BigField();
        $version = $BigField->where([
            ['seller_id', '=', $this->admin['seller_id']],
            ['theme_id', '=', $theme['id']],
        ])->max('version');
        $version = $version ?: 0;
        $version++;

        $version = intval($version);

        \phpQuery::each($html['body .huocms-block'], function ($key, $item) use ($html, &$blockHtmlArr, $param, $themeName, $saveType, $theme, $version) {
            $domObj = $html['.huocms-block:eq('.$key.')'];
            $includePath = $domObj->attr('data-inclue-path'); // 自己有包含路径或某个子元素有包含路径，需要将代码替换掉

            $components = $domObj->find('.huocms-components');
            foreach ($components as $obj) {
                $subIncludePath = pq($obj)->attr('data-inclue-path');
                if (!empty($subIncludePath)) {
                    if (pq($obj)->hasClass('huocms-static-edit')) {
                        $content = pq($obj)->htmlOuter();
                        $themeFileName = "{$subIncludePath}.html";
                        $filename = $subIncludePath;
                        ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version);
                    }

                    $includeHtml = '
                    {include file="'.$subIncludePath.'"}
                    ';
                    $next = pq($obj)->next();
                    $parent = pq($obj)->parent();
                    if (empty($next->html())) {
                        pq($obj)->remove();
                        $parent->append($includeHtml);
                    } else {
                        pq($obj)->remove();
                        $next->before($includeHtml);
                    }
                }
            }

            $blockHtml = '';
            if (!empty($includePath)) {
                if ($domObj->hasClass('huocms-static-edit')) {
                    $content = $domObj->htmlOuter();
                    $themeFileName = "{$includePath}.html";
                    $filename = $includePath;
                    ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version);
                }

                $domObj = '
                {include file="'.$includePath.'"}
                ';
                $blockHtml = $domObj;
                $blockHtmlArr[] = $blockHtml;
                return $item;
            }

            $tmpTemplate = $domObj->attr('data-huocms-block');
            $blockId = $domObj->attr('data-huocms-blockid');
            $blockType = $this->getBlockType($domObj);

//            echo $blockType . '<br/>';

            if (!empty($tmpTemplate) && !empty($blockId)) {

                $blockTemplatePath = CMS_ROOT . $this->designBase . DIRECTORY_SEPARATOR . $tmpTemplate;
                $blockHtml = file_get_contents($blockTemplatePath);
                $blockHtml = $this->replaceHtml($blockType, $blockId, $blockHtml, $domObj);
            } else {
                $blockHtml = $domObj;
            }

            $blockHtmlArr[] = $blockHtml;
            return $item;
        });

        $html['body .huocms-block']->remove();
        $html['body #think_page_trace']->remove();
        $html['body #think_page_trace_open']->remove();
        $blockHtmlArr = array_reverse($blockHtmlArr);
        foreach ($blockHtmlArr as $value) {
            $html['body']->prepend($value);
        }
//        exit();
        //保存生成的html

        $pathInfo = pathinfo($param['file']);
        $filename = $pathInfo['filename'];

        $filePath = CMS_ROOT .  "public/themes/website/{$param['website_id']}/{$param['lang']}/{$themeName}/{$filename}.html";
        $viewFilePath = CMS_ROOT .  "public/themes/hc_original/{$themeName}/{$filename}.html";

        // 替换SEO
        $html['head meta[name="description"]']->remove();
        $html['head meta[name="keywords"]']->remove();
        $html['head title']->remove();
        $html['head']->prepend($this->getSeoHtml());

        $themeFileName = "{$filename}.html";

        // 保存至版本数据库中
        $content = $html->html();
        ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version);

        if ($saveType == 1) {
            echo "保存成功 !";
            return;
        }

        //更新theme_file
        $themeService = new ThemeService();
        $suffix = config('view.view_suffix');
        $res = $themeService->publishThemeFile($theme['id'],$param['website_id'],$this->admin['seller_id'],$suffix, $version);
        $res = $res->getData();
        if ($res['code'] != 0) {
            echo $res['msg'];
            return;
        }

        $themeFileModel->updateThemeFile([
            ['file', '=', $themeFileName],
            ['website_id', '=', $param['website_id']],
            ['lang', '=', $param['lang']],
        ], ['is_design' => 1, 'design_path' => $themeFileName]);

        echo "发布成功 !";
        return;
    }

    protected function getBlockType($node) {
        $classes = explode( ' ', $node->attr('class'));
        $blockType = '';
        foreach ($classes as $class) {
            if ($class != 'huocms-components' && $class != 'huocms-block') {
                $blockType = $class;
                break;
            }
        }
        return $blockType;
    }

    public function replaceHtml($blockType, $id, $html, $node)
    {
        if (strpos($blockType, 'block') !== false) {
            // 替换模板里的navID
            $blockHtml = str_replace('hcTaglib:category id="1"', 'hcTaglib:category id="' . $id . '"', $html);
        } elseif ($blockType == 'huocms-nav') {
            // 替换模板里的navID
            $blockHtml = str_replace('hcTaglib:nav cid="2"', 'hcTaglib:nav cid="' . $id . '"', $html);
        } elseif ($blockType == 'huocms-banner') {
            // 替换模板里的navID
            $blockHtml = str_replace('hcTaglib:slide cid="1"', 'hcTaglib:slide cid="' . $id . '"', $html);
        } else {
            $blockHtml = $node;
        }
        return $blockHtml;
    }

    public function getSeoHtml()
    {
        return '
    <title>{$current_cate.seo_title|default=$current_cate.title}</title>
    <meta name="description" content="{$current_cate.seo_description|default=$current_cate.title}">
    <meta name="keywords" content="{$current_cate.seo_keywords|default=$current_cate.title}">';
    }


    // setting接口
    public function getSetting()
    {

    }

    /**
     * 单个链接列表接口
     * 基础链接：客服链接，icp备案链接，公安备案链接
     * 栏目链接
     * 内容链接
     * @return Json
     */
    public function getLinkList()
    {
        $param = $this->request->param();
        // 数据验证
        try {
            validate(WebsiteSettingValidate::class)->scene('read')->check($param);
        } catch (ValidateException $e) {
            return jsonReturn(-1, $e->getError());
        }
        $where = [
            'seller_id' => $this->admin['seller_id'],
            'website_id' => $param['website_id'],
            'lang' => $param['lang'],
        ];

        $websiteSetting = new WebsiteSetting();
        $res = $websiteSetting->getWebsiteSetting($where);
        $res['data'] = $res['data']->toArray();
        $res['data']['setting'] = json_decode($res['data']['setting'], true);
        $link = [
            'name' => '基本链接',
            'value' => '',
            'child' => [
                [
                    'name' => '客服链接',
                    'value' => $res['data']['setting']['customer_code'] ?? '',
                ],
                [
                    'name' => 'icp备案链接',
                    'value' => $res['data']['setting']['icp_link'] ?? '',
                ],
                [
                    'name' => '公网安备链接',
                    'value' => $res['data']['setting']['gwa_link'] ?? '',
                ],
            ]
        ];

        $categoryList = $this->categoryList();

        $cate = [
            'name' => '栏目链接',
            'value' => '',
            'child' => $categoryList,
        ];


        $data = [
            'link' => $link,
            'cate' => $cate,
            'content' => [],
        ];

        return jsonReturn(0, '成功', $data);
    }

    // 导航接口
    public function getNavList()
    {

    }

    // 友情链接接口
    public function getFriendLink()
    {

    }

    public function getCategoryList()
    {
        return jsonReturn(0, '成功', $this->categoryList());
    }

    public function categoryListSetWhere(&$where, $type)
    {
        switch ($type) {
            case 'suq_block1':
            case 'suq_block2_contact':
            case 'suq_block3':
            case 'suq_block4':
            case 'suq_block5':
            case 'suq_block6':
            case 'suq_footer':
                $where[] = ['type', 'in', [2,3]];
                $where[] = ['id', '>', 1];
                break;
            case 'suq_block2':
                $where[] = ['id', '>', 1];
                break;
            default:
                break;
        }
    }

    // 栏目列表接口
    protected function categoryList()
    {
        $param = $this->request->param();
        $where = [
            ['seller_id', '=', $this->admin['seller_id']],
            ['website_id', '=', $param['website_id']],
        ];
        $lang = $param['lang'] ?? '';
        if (empty($lang)) {
            $lang = 'zh';
        }
        $Website = new Website();
        $website = $Website->getWebsite(['id' => $param['website_id'], 'seller_id' => $this->admin['seller_id']])['data'];
        $domain = $website['domain'];
        if ($lang != 'zh') {
            $domain = $domain . '/' . $lang;
        }
        $where[] = ['lang', '=', $lang];

        if(isset($param['type'])) {
            $this->categoryListSetWhere($where, $param['type']);
        }

        $cateModel = new Category();
        $categoryList = $cateModel->where($where)->field('id,type,title,alias')->select()->each(function (&$item) use ($domain) {
            if ($item['type'] == 1 || $item['type'] == 4) {
                if (!empty($item['alias'])) {
                    if ($item['alias'] == '/') {
                        $item['fullUrl'] = 'http://' . $domain;
                    } else {
                        $item['fullUrl'] = 'http://' . $domain . $item['alias'] . '.' . config('route.url_html_suffix');
                    }
                } else {
                    $item['fullUrl'] = 'http://' . $domain . '/list/index/' . $item['id'] . '.' . config('route.url_html_suffix');
                }
            } else if ($item['type'] == 3) {
                $item['fullUrl'] = $item['alias'];
            } else {
                $item['fullUrl'] = 'javascript:;';
            }
        });
        return $categoryList->toArray();
    }

    // 栏目内容接口
    public function getCategoryData()
    {
        $param = $this->request->param();
        $categoryModel = new Category();
        $contentModel = new SubContent();
        $category = [];
        $subCategory = [];
        //获取此栏目数据和下面所有子栏目数据，并且拿到所有栏目下的内容数据
        if ($param['type'] == 'suq_block1') {
            //获取选择栏目的的标题和副标题，再获取子栏目的名称和缩略图
            //最后获取子栏目的内容列表
            $category = $categoryModel->getCategory([
                ['id', '=', $param['category_id']],
                ['type', 'in', [2,3]],
            ], [], 'id, type, title, sub_title, alias')['data'];
            $subCategory = $categoryModel->where([
                ['parent_id', '=', $param['category_id']],
                ['type', 'in', [2,3]],
            ])->with(['thumbnail'])->field('id, type, title, sub_title, desc, thumbnail, alias')->select();

            foreach ($subCategory as &$subCate) {
                $subCate['content'] = $contentModel->alias('a')
                    ->join('category_sub_content b', 'b.sub_content_id = a.id', 'left')
                    ->with(['thumbnail'])
                    ->where([
                        ['b.category_id', '=', $subCate['id']]
                    ])
                    ->field('a.id, title, thumbnail')
                    ->select();
            }
        } else if ($param['type'] == 'suq_block2' ||
            $param['type'] == 'suq_block3' ||
            $param['type'] == 'suq_block4' ||
            $param['type'] == 'suq_footer') {
            $category = $categoryModel->getCategory([
                ['id', '=', $param['category_id']],
                ['type', 'in', [2,3]],
            ], ['thumbnail'], 'id, type, title, sub_title, desc, alias, thumbnail, description')['data'];
            $contentList = $contentModel->alias('a')
                ->join('category_sub_content b', 'b.sub_content_id = a.id', 'left')
                ->with(['thumbnail'])
                ->where([
                    ['b.category_id', '=', $param['category_id']]
                ])
                ->field('a.id, title, sub_title, description, thumbnail')
                ->select()->toArray();

            foreach ($contentList as &$value) {
                if (isset($value['thumbnail']['url'])) {
                    $value['thumbnail_url'] = $value['thumbnail']['url'];
                }
                if (in_array($category['type'], [1,2,4])) {
                    $value['href'] = hcUrl('detail/index', ['cid' => $param['category_id'], 'id' => $value['id']]);
                } else {
                    $value['href'] = $category['alias'];
                }
            }

            $category['content'] = $contentList;
        } else if ($param['type'] == 'suq_block5' ||
            $param['type'] == 'suq_block6' ||
            $param['type'] == 'suq_block2_contact') {
            $category = $categoryModel->getCategory([
                ['id', '=', $param['category_id']],
                ['type', 'in', [2,3]],
            ], ['thumbnail'], 'id, type, title, sub_title, desc, alias, thumbnail, description, seo_description')['data'];
        }
        $returnData = [
            'category' => $category,
            'subCategory' => $subCategory,
        ];
        return jsonReturn(0, '成功', $returnData);

    }

    // 内容列表接口
    public function getContentList()
    {

    }


    // 内容详情接口

    // 幻灯片接口

    // 广告接口


    // 获取模板文件历史版本
    public function getHistoryList()
    {
        $param = $this->request->param();
        $initPage = $param['init_page'] ?? 'index';
        $initPageName = $initPage . '.html';
        $param['limit'] = $param['limit'] ?? 100;

        $themeModel = new Theme();
        $themeId = $themeModel->where([
            ['website_id', '=', $param['website_id']],
            ['lang', '=', $param['lang']],
            ['is_active', '=', 1],
        ])->value('id');

        if (empty($themeId)) {
            return jsonReturn(-1, '当前站点没有激活的模板，请先去安装模板');
        }

        // 获取当前模板文件id
        $themeFileModel = new ThemeFile();
        $themeFileId = $themeFileModel->where([
            ['website_id', '=', $param['website_id']],
            ['lang', '=', $param['lang']],
            ['theme_id', '=', $themeId],
            ['file', '=', $initPageName],
        ])->value('id');

        if (empty($themeFileId)) {
            return jsonReturn(-2, '模板文件不存在');
        }

        $bigFieldModel = new BigField();
        $list = $bigFieldModel->alias('a')
            ->join('admin b', 'b.id = a.admin_id', 'left')
            ->join('theme_file c', 'a.theme_file_id = c.id')
            ->where([
            ['a.theme_id', '=', $themeId],
            ['a.theme_file_id', '=', $themeFileId],
        ])->field('a.*, b.name as admin_name, c.file')->order('id desc')->paginate($param['limit']);

        return json(pageReturn(dataReturn(0, '', $list)));
    }

    public function setPreviewPage()
    {
        $param = $this->request->param();
        $initPage = $param['init_page'] ?? 'index';
        $initPageName = $initPage . '.html';
        $version = $param['version'] ?? 1; // 将此版本的所有文件都塞入view下

        $themeModel = new Theme();
        $theme = $themeModel->where([
            ['website_id', '=', $param['website_id']],
            ['lang', '=', $param['lang']],
            ['is_active', '=', 1],
        ])->field('id, theme')->find();

        if (empty($theme['id'])) {
            return jsonReturn(-1, '当前站点没有激活的模板，请先去安装模板');
        }

        ThemeService::updatePreviewFile($param, $version, $theme);

        session('history-view', time());

        return jsonReturn(0, '预览初始化成功');
    }

}
